﻿#include "Dict.h"
#include<iostream>
#include<fstream>
#include <direct.h>
#include <map>
#include <io.h>
#include"file_manager.h"
#include"sql\Stat.h"
#include "page.h"

using namespace std;

Dict* Dict::instance = nullptr;
string Dict::curSchema;
map<int, pair <RoidType, string>> Dict::roidmap;

Dict* Dict::getInstance()
{
	if (instance == nullptr) {
		instance = new Dict;
		instance->Init();
	}
	return instance;
}

void Dict::release()
{
	if (instance != nullptr) {
		delete instance;
		instance = nullptr;
	}
	storemap();
}

void Dict::InitDictionary()
{
	FileManager* blkmgr = FileManager::getInstance();
	_mkdir("data");
	ofstream fout("./data/dict_oid.oid", ios::out);	//创建oid文件
	fout << 1;
	fout.close();
	fout.clear();



	file file_user = *blkmgr->getFile(blkmgr->allocFile());
	file file_database = *blkmgr->getFile(blkmgr->allocFile());
	file file_class = *blkmgr->getFile(blkmgr->allocFile());
	file file_attribute = *blkmgr->getFile(blkmgr->allocFile());
	file file_index = *blkmgr->getFile(blkmgr->allocFile());


	string block1;
	string fileid = file_user.fileid64;
	string str = "./data/data_" + fileid + ".db";		//创建user表文件
	fout.open(str, ios::out);
	fout.close();
	fout.clear();
	block1 = FileManager::getInstance()->allocPage(fileid);	//为文件分配第一个页

	/**/
	fout.open("./data/firstblockid.bid", ios::out | ios::app);
	fout << block1 << "\n";									//将第一个页号写入
	fout.close();
	fout.clear();
	/**/

	fileid = file_database.fileid64;
	str = "./data/data_" + fileid + ".db";			//创建database表文件
	fout.open(str, ios::out);
	fout.close();
	fout.clear();
	block1 = FileManager::getInstance()->allocPage(fileid);	//为文件分配第一个页

	/**/
	fout.open("./data/firstblockid.bid", ios::out | ios::app);
	fout << block1 << "\n";
	fout.close();
	fout.clear();
	/**/

	fileid = file_class.fileid64;
	str = "./data/data_" + fileid + ".db";			//创建class表文件
	fout.open(str, ios::out);
	fout.close();
	fout.clear();
	block1 = FileManager::getInstance()->allocPage(fileid);	//为文件分配第一个页

	/**/
	fout.open("./data/firstblockid.bid", ios::out | ios::app);			//创建一个文件，放所有class的rowid
	fout << block1 << "\n";									//将第一个页号写入
	fout.close();
	fout.clear();
	/**/

	fileid = file_attribute.fileid64;
	str = "./data/data_" + fileid + ".db";			//创建attribute表文件
	fout.open(str, ios::out);
	fout.close();
	fout.clear();
	block1 = FileManager::getInstance()->allocPage(fileid);	//为文件分配第一个页

	/**/
	fout.open("./data/firstblockid.bid", ios::out | ios::app);			//创建一个文件，放所有attribute的rowid，				##这个有待商榷
	fout << block1 << "\n";									//将第一个页号写入
	fout.close();
	fout.clear();
	/**/

	fileid = file_index.fileid64;
	str = "./data/data_" + fileid + ".db";			//创建index表文件
	fout.open(str, ios::out);
	fout.close();
	fout.clear();
	block1 = FileManager::getInstance()->allocPage(fileid);	//为文件分配第一个页

	/**/
	fout.open("./data/firstblockid.bid", ios::out | ios::app);			//创建一个文件，放所有index的rowid，				##这个有待商榷
	fout << block1 << "\n";									//将第一个页号写入
	fout.close();
	fout.clear();
	/**/
}

void Dict::Init()
{
	_mkdir("data");
	int isExist = _access("./data/dict_oid.oid", 0);
	if (isExist == -1) {
		InitDictionary();
		User* user = CreateUser();
		user->SetUserid(DeliverOid());
		user->SetUsername("csu");
		user->SetCode("666666");
		StoreUser(user);
	}

	Initmap();
	Oid::GetInstance();						//新建oid计数


	//将各个文件第一页的页号放到类中
	ifstream fin("./data/firstblockid.bid", ios::in);

	getline(fin, userblock1);

	getline(fin, databaseblock1);

	getline(fin, classblock1);

	getline(fin, attributeblock1);

	getline(fin, indexblock1);

	fin.close();
	fin.clear();
}

void Dict::Initmap()
{
	ifstream fin("./data/dict.roid", ios::in);			//打开保存rowid的文件
	string line;
	while (getline(fin, line)) {
		if (line != "") {
			Stat* stat = Page::stringToStat(line);
			roidmap[(*(stat->statList))[0]->ival] = make_pair((RoidType)(*(stat->statList))[1]->ival, (*(stat->statList))[2]->name);
		}
	}
}

void Dict::storemap()
{
	ofstream fout("./data/dict.roid", ios::out);			//打开保存rowid的文件
	for (auto item : roidmap) {
		vector<Stat*> stats;
		Stat* oidStat = Stat::makeLiteral((int64_t)item.first);
		Stat* roidTypeStat = Stat::makeLiteral((int64_t)item.second.first);
		Stat* ridStat = Stat::makeLiteral(item.second.second.c_str());
		stats.push_back(oidStat);
		stats.push_back(roidTypeStat);
		stats.push_back(ridStat);
		Stat* resStat = Stat::makeArray(&stats);
		string resstr = Page::statToString(resStat);
		fout << resstr << endl;
	}
	fout.close();
	fout.clear();
}

int Dict::DeliverOid() {
	return Oid::GetInstance()->GetCurNum();	//获得当前的oid
}

User* Dict::CreateUser() {
	return new User;
}

Database* Dict::CreateDatabase() {
	return new Database;
}

Class* Dict::CreateClass() {
	return new Class;
}

Attribute* Dict::CreateAttribute() {
	return new Attribute;
}

Index* Dict::CreateIndex() {
	return new Index;
}


User* Dict::GetUser(string username) {
	User* targetuser = CreateUser();			//创建一个空的User用于装结果
	string tempusername;						//用于装读出的username
	vector<string> rowidList;
	for (auto item : roidmap) {
		if (item.second.first == UserRoid)
			rowidList.push_back(item.second.second);
	}
	vector<Stat*>tempstat = FileManager::getInstance()->multipleGet(rowidList);
	vector<Stat*>::iterator iter;
	for (iter = tempstat.begin(); iter != tempstat.end(); iter++) {
		tempusername = (*((*iter)->statList))[1]->name;
		if (tempusername == username) {		//找到
			targetuser->SetUserid((*((*iter)->statList))[0]->ival);
			targetuser->SetUsername(username);
			targetuser->SetCode((*((*iter)->statList))[2]->name);
			return targetuser;
		}
	}
	return nullptr;			//如果都遍历完了还没找到，那么不存在这一项
}


Database* Dict::GetDatabase(User* user, string dbname) {
	Database* targetdatabase = CreateDatabase();			//创建一个空的User用于装结果

	int userid = user->GetUserid();

	int tempuserid;
	string tempdaname;

	vector<string> rowidList;
	for (auto item : roidmap) {
		if (item.second.first == DatabaseRoid)
			rowidList.push_back(item.second.second);
	}
	vector<Stat*>tempstat = FileManager::getInstance()->multipleGet(rowidList);

	vector<Stat*>::iterator iter;
	for (iter = tempstat.begin(); iter != tempstat.end(); iter++) {
		tempuserid = (*((*iter)->statList))[2]->ival;
		tempdaname = (*((*iter)->statList))[1]->name;

		if (tempdaname == dbname && tempuserid == userid) {		//找到
			targetdatabase->oid = ((*((*iter)->statList))[0]->ival);
			targetdatabase->datname = dbname;
			targetdatabase->ownerid = ((*((*iter)->statList))[2]->ival);
			targetdatabase->datconnlimit = ((*((*iter)->statList))[3]->ival);
			targetdatabase->curconnect = ((*((*iter)->statList))[4]->ival);
			vector<Stat*> gg = *((*((*iter)->statList))[5]->statList);
			vector<Stat*>::iterator it;
			for (it = gg.begin(); it != gg.end(); it++) {
				targetdatabase->datacl.push_back((*it)->ival);
			}

			return targetdatabase;
		}
	}

	return nullptr;			//如果都遍历完了还没找到，那么不存在这一项
}


vector<Database*> Dict::getDatabases(User* user)
{
	vector<Database*> res;
	Database* targetdatabase = CreateDatabase();			//创建一个空的User用于装结果

	int userid = user->GetUserid();

	int tempuserid;
	string tempdaname;

	vector<string> rowidList;
	for (auto item : roidmap) {
		if (item.second.first == DatabaseRoid)
			rowidList.push_back(item.second.second);
	}
	vector<Stat*>tempstat = FileManager::getInstance()->multipleGet(rowidList);

	vector<Stat*>::iterator iter;
	for (iter = tempstat.begin(); iter != tempstat.end(); iter++) {
		tempuserid = (*((*iter)->statList))[2]->ival;
		tempdaname = (*((*iter)->statList))[1]->name;

		if (tempuserid == userid) {		//找到
			targetdatabase->oid = ((*((*iter)->statList))[0]->ival);
			targetdatabase->datname = ((*((*iter)->statList))[1]->name);
			targetdatabase->ownerid = ((*((*iter)->statList))[2]->ival);
			targetdatabase->datconnlimit = ((*((*iter)->statList))[3]->ival);
			targetdatabase->curconnect = ((*((*iter)->statList))[4]->ival);
			vector<Stat*> gg = *((*((*iter)->statList))[5]->statList);
			vector<Stat*>::iterator it;
			for (it = gg.begin(); it != gg.end(); it++) {
				targetdatabase->datacl.push_back((*it)->ival);
			}
			res.push_back(new Database(*targetdatabase));
		}
	}

	delete targetdatabase;
	return res;
}


Class* Dict::GetClass(Database* tdatabase, string relationname) {
	Class* targetclass = CreateClass();			//创建一个空的Class用于装结果

	int databaseid = tdatabase->GetOid();

	int temp_databaseid;
	string temp_relationname;


	vector<string> rowidList;
	for (auto item : roidmap) {
		if (item.second.first == ClassRoid)
			rowidList.push_back(item.second.second);
	}
	vector<Stat*>tempstat = FileManager::getInstance()->multipleGet(rowidList);

	vector<Stat*>::iterator iter;
	for (iter = tempstat.begin(); iter != tempstat.end(); iter++) {
		temp_databaseid = (*((*iter)->statList))[1]->ival;

		temp_relationname = (*((*iter)->statList))[2]->name;

		if (temp_databaseid == databaseid && temp_relationname == relationname) {		//找到

			targetclass->oid = ((*((*iter)->statList))[0]->ival);

			targetclass->databaseid = ((*((*iter)->statList))[1]->ival);

			targetclass->relname = ((*((*iter)->statList))[2]->name);

			targetclass->relfileid = ((*((*iter)->statList))[3]->name);

			targetclass->relblockid = ((*((*iter)->statList))[4]->name);

			targetclass->reltuples = ((*((*iter)->statList))[5]->ival);

			targetclass->hasindex = ((*((*iter)->statList))[6]->ival);

			targetclass->relkind = *((*((*iter)->statList))[7]->name);

			targetclass->relnatts = ((*((*iter)->statList))[8]->ival);

			targetclass->haspkey = ((*((*iter)->statList))[9]->ival);
			return targetclass;
		}
	}

	return nullptr;			//如果都遍历完了还没找到，那么不存在这一项

}

vector<Class*> Dict::getClasses(Database* tdatabase)
{
	vector<Class*> res;
	Class* targetclass = CreateClass();			//创建一个空的Class用于装结果

	int databaseid = tdatabase->GetOid();

	int temp_databaseid;
	string temp_relationname;


	vector<string> rowidList;
	for (auto item : roidmap) {
		if (item.second.first == ClassRoid)
			rowidList.push_back(item.second.second);
	}
	vector<Stat*>tempstat = FileManager::getInstance()->multipleGet(rowidList);
	vector<Stat*>::iterator iter;
	for (iter = tempstat.begin(); iter != tempstat.end(); iter++) {
		temp_databaseid = (*((*iter)->statList))[1]->ival;

		temp_relationname = (*((*iter)->statList))[2]->name;

		if (temp_databaseid == databaseid) {		//找到

			targetclass->oid = ((*((*iter)->statList))[0]->ival);

			targetclass->databaseid = ((*((*iter)->statList))[1]->ival);

			targetclass->relname = ((*((*iter)->statList))[2]->name);

			targetclass->relfileid = ((*((*iter)->statList))[3]->name);

			targetclass->relblockid = ((*((*iter)->statList))[4]->name);

			targetclass->reltuples = ((*((*iter)->statList))[5]->ival);

			targetclass->hasindex = ((*((*iter)->statList))[6]->ival);

			targetclass->relkind = *((*((*iter)->statList))[7]->name);

			targetclass->relnatts = ((*((*iter)->statList))[8]->ival);

			targetclass->haspkey = ((*((*iter)->statList))[9]->ival);
			res.push_back(targetclass);
		}
	}

	return res;

}


vector<Attribute*>	Dict::GetAttribute(Class* table) {
	vector<Attribute*> allarrtibute;			//定义返回值

	int relid = table->oid;						//表的编号
	int totalnum = table->relnatts;				//表总共有几个属性

	int i = 0;		//找到几个属性
	int temp_relid;			//属性所属的表的id

	Attribute* tempattritube = CreateAttribute();
	delete tempattritube;

	vector<string> rowidList;
	for (auto item : roidmap) {
		if (item.second.first == AttributeRoid)
			rowidList.push_back(item.second.second);
	}
	vector<Stat*>tempstat = FileManager::getInstance()->multipleGet(rowidList);

	vector<Stat*>::iterator iter;
	for (iter = tempstat.begin(); iter != tempstat.end(); iter++) {
		temp_relid = (*((*iter)->statList))[1]->ival;

		if (temp_relid == relid) {		//找到

			Attribute* targetattribute = CreateAttribute();			//创建一个空的Attribute用于装结果

			targetattribute->oid = ((*((*iter)->statList))[0]->ival);

			targetattribute->relid = ((*((*iter)->statList))[1]->ival);

			targetattribute->name = ((*((*iter)->statList))[2]->name);

			targetattribute->type = (StatType)((*((*iter)->statList))[3]->ival);

			targetattribute->attnum = ((*((*iter)->statList))[4]->ival);

			targetattribute->varcharlen = ((*((*iter)->statList))[5]->ival);

			targetattribute->notnull = ((*((*iter)->statList))[6]->ival);

			targetattribute->pkey = ((*((*iter)->statList))[7]->ival);

			targetattribute->colcard = ((*((*iter)->statList))[8]->ival);

			allarrtibute.push_back(targetattribute);

			i++;

			if (i == totalnum) {
				return allarrtibute;
			}
		}
	}

	return allarrtibute;			//没找到或者没找全都返回

}



Attribute* Dict::GetAttribute(int attritubeid) {
	Attribute* targetattribute = CreateAttribute();			//创建一个空的Attribute用于装结果

	int temp_attributeid;						//用于装读出的attributeid

	vector<string> rowidList;
	for (auto item : roidmap) {
		if (item.second.first == AttributeRoid)
			rowidList.push_back(item.second.second);
	}
	vector<Stat*>tempstat = FileManager::getInstance()->multipleGet(rowidList);
	vector<Stat*>::iterator iter;
	for (iter = tempstat.begin(); iter != tempstat.end(); iter++) {

		temp_attributeid = (*((*iter)->statList))[0]->ival;

		if (temp_attributeid == attritubeid) {		//找到

			targetattribute->oid = ((*((*iter)->statList))[0]->ival);

			targetattribute->relid = ((*((*iter)->statList))[1]->ival);

			targetattribute->name = ((*((*iter)->statList))[2]->name);

			targetattribute->type = ((*((*iter)->statList))[3]->type);

			targetattribute->attnum = ((*((*iter)->statList))[4]->ival);

			targetattribute->varcharlen = ((*((*iter)->statList))[5]->ival);

			targetattribute->notnull = ((*((*iter)->statList))[6]->ival);

			targetattribute->pkey = ((*((*iter)->statList))[7]->ival);

			targetattribute->colcard = ((*((*iter)->statList))[8]->ival);

			return targetattribute;
		}
	}
	return nullptr;			//如果都遍历完了还没找到，那么不存在这一项
}



vector<Attribute*>	Dict::GetAttribute(Index* index) {
	vector<Attribute*> allarrtibute;			//定义返回值

	vector<int>::iterator iter;
	for (iter = index->indkeys.begin(); iter != index->indkeys.end(); iter++) {		//按照attribute对应的所有属性id取出所有属性
		allarrtibute.push_back(GetAttribute(*iter));
	}

	return allarrtibute;

}


Index* Dict::GetIndex(Class* tindex) {
	Index* targetindex = CreateIndex();			//创建一个空的Index用于装结果

	int indexrelid = tindex->oid;				//数据库对象（索引）对应的oid
	int temp_indexrelid;						//用于装读出的indexrelid
	string tempblockid = indexblock1;			//遍历文件用的页


	//遍历所有页，同时在文件中找到对应项目，并且判断indexrelid是否相等
	do {
		Page* tempblock = FileManager::getInstance()->getPage(targetindex->fileid, tempblockid);

		vector<Stat*> tempstat = tempblock->get(0, tempblock->getdatanumber() - 1);
		vector<Stat*>::iterator iter;
		for (iter = tempstat.begin(); iter != tempstat.end(); iter++) {

			temp_indexrelid = (*((*iter)->statList))[0]->ival;

			if (temp_indexrelid == indexrelid) {		//找到

				targetindex->indexrelid = ((*((*iter)->statList))[0]->ival);

				targetindex->indrelid = ((*((*iter)->statList))[1]->ival);

				targetindex->indnatts = ((*((*iter)->statList))[2]->ival);

				targetindex->name = ((*((*iter)->statList))[3]->name);

				targetindex->indtype = *((*((*iter)->statList))[4]->name);

				vector<Stat*> gg = *((*((*iter)->statList))[5]->statList);
				vector<Stat*>::iterator it;
				for (it = gg.begin(); it != gg.end(); it++) {
					targetindex->indkeys.push_back((*it)->ival);
				}

				return targetindex;
			}
		}

		tempblockid = tempblock->getNextPageid();

	} while (tempblockid != "");						//如果下一个页的页号是空的话，表示所有文件都遍历完了

	return nullptr;			//如果都遍历完了还没找到，那么不存在这一项
}


void Dict::StoreUser(User* tuser) {
	tuser->StoreToFile();
}

void Dict::StoreDatabase(Database* tdatabase) {
	tdatabase->StoreToFile();
}

void Dict::StoreClass(Class* tclass) {
	tclass->StoreToFile();
}

void Dict::StoreAttribute(Attribute* tattribute) {
	tattribute->StoreToFile();
}

void Dict::StoreIndex(Index* tindex) {
	tindex->StoreToFile();
}

void Dict::UpdateUser(User* tuser)
{
	tuser->updateFile();
}

void Dict::UpdateDatabase(Database* tdatabase)
{
	tdatabase->updateFile();
}

void Dict::UpdateClass(Class* tclass)
{
	tclass->updateFile();
}

void Dict::UpdateAttribute(Attribute* tattribute)
{
	tattribute->updateFile();
}


string Dict::getRowid(int oid)
{
	return roidmap[oid].second;
}



/*-------------------------------------------------*/
Oid* Oid::instance = nullptr;

Oid::Oid(string tfilename) {
	filename = tfilename;
}

Oid* Oid::GetInstance()
{
	if (instance == nullptr) {
		instance = new Oid("./data/dict_oid.oid");
		instance->Load();
	}
	return instance;
}

void Oid::Release()
{
	if (instance != nullptr) {
		instance->Store();
		delete instance;
		instance = nullptr;
	}
}

int Oid::GetCurNum()
{
	return curnum++;
}

void Oid::Load()
{
	ifstream fin(filename, ios::in);
	fin >> curnum;
	fin.close();
}

void Oid::Store()
{
	ofstream fout(filename, ios::out);
	fout << curnum;
	fout.close();
}
/*-------------------------------------------------*/


/*-------------------------------------------------*/
User::User() {
	userid = 0;
	username = "";
	code = "";
	file file_user = file(0);
	fileid = file_user.fileid64;
}

int User::GetUserid() {
	return userid;
}

void User::SetUserid(int tuserid) {
	userid = tuserid;
}

string User::GetUsername() {
	return username;
}

void User::SetUsername(string tusername) {
	username = tusername;
}

string User::GetCode() {
	return code;
}

void User::SetCode(string tcode) {
	code = tcode;
}

void User::updateFile()
{
	//生成要放入的数据final
	Stat* stat_userid = Stat::makeLiteral((int64_t)userid);		//		##此处有问题
	Stat* stat_username = Stat::makeLiteral(username.data());
	Stat* stat_code = Stat::makeLiteral(code.data());
	vector<Stat*> Statlist;
	Statlist.push_back(stat_userid);
	Statlist.push_back(stat_username);
	Statlist.push_back(stat_code);
	Stat* final = Stat::makeArray(&Statlist);

	FileManager::getInstance()->update(Dict::getRowid(GetUserid()).c_str(), final);

}

void User::StoreToFile() {
	//Block* targetblock = BlockMgr::getInstance()->getBlock(fileid, userblock1);		//取得文件中第一个页

	//生成要放入的数据final
	Stat* Stat_userid = Stat::makeLiteral((int64_t)userid);		//		##此处有问题
	Stat* Stat_username = Stat::makeLiteral(username.data());
	Stat* Stat_code = Stat::makeLiteral(code.data());
	vector<Stat*> Statlist;
	Statlist.push_back(Stat_userid);
	Statlist.push_back(Stat_username);
	Statlist.push_back(Stat_code);
	Stat* final = Stat::makeArray(&Statlist);

	string rowid;
	Page* targetblock = FileManager::getInstance()->getLastAvailablePage(fileid);		//取得file的最后一个可用的页
	rowid = targetblock->put(final);									//将数据放入可以放入的页
	targetblock->updateBuffer();

	Dict::roidmap[userid] = make_pair(UserRoid, rowid);
}



/*-------------------------------------------------*/


/*-------------------------------------------------*/
Database::Database()
{
	datconnlimit = 1;		//默认最大并发访问1个用户
	curconnect = 0;			//当前0个访问
	file file_database = file(1);
	fileid = file_database.fileid64;
}

int Database::GetOid() {
	return oid;
}

void Database::SetOid(int toid) {
	oid = toid;
}

string Database::GetDatName() {
	return datname;
}

void Database::SetDatName(string tdatname)
{
	datname = tdatname;
}

int Database::GetOwnerid() {
	return ownerid;
}

void Database::SetOwnerid(int townerid)
{
	ownerid = townerid;
}

int Database::GetDatconnlimit()
{
	return datconnlimit;
}

void Database::SetDatconnlimit(int tdatconnlimit)
{
	datconnlimit = tdatconnlimit;
}

void Database::SetDatacl(vector<int> tdatacl) {
	datacl = tdatacl;
}

bool Database::IsAvailable(int userid) {
	vector<int>::iterator iter;
	for (iter = datacl.begin(); iter != datacl.end(); iter++)
	{
		if ((*iter) == userid) {
			return true;			//该user有权限
		}
	}
	return false;
}

bool Database::CanConnect()
{
	if (curconnect < datconnlimit) {
		return true;			//小于最大连接数，可以连接
	}
}

void Database::Addconnect() {
	curconnect++;
}


void Database::updateFile()
{
	Stat* stat_oid = Stat::makeLiteral((int64_t)oid);
	Stat* stat_datname = Stat::makeLiteral(datname.data());
	Stat* stat_ownerid = Stat::makeLiteral((int64_t)ownerid);
	Stat* stat_datconnlimit = Stat::makeLiteral((int64_t)datconnlimit);
	Stat* stat_curconnect = Stat::makeLiteral((int64_t)curconnect);
	vector<Stat*> acl;
	vector<int>::iterator iter;
	for (iter = datacl.begin(); iter != datacl.end(); iter++)
	{
		acl.push_back(Stat::makeLiteral((int64_t)(*iter)));
	}
	Stat* stat_datacl = Stat::makeArray(&acl);

	//生成最终要放入的final
	vector<Stat*> statlist;
	statlist.push_back(stat_oid);
	statlist.push_back(stat_datname);
	statlist.push_back(stat_ownerid);
	statlist.push_back(stat_datconnlimit);
	statlist.push_back(stat_curconnect);
	statlist.push_back(stat_datacl);
	Stat* final = Stat::makeArray(&statlist);

	FileManager::getInstance()->update(Dict::getRowid(oid).c_str(), final);
}

void Database::StoreToFile() {
	//生成各条要放入的数据
	Stat* stat_oid = Stat::makeLiteral((int64_t)oid);
	Stat* stat_datname = Stat::makeLiteral(datname.data());
	Stat* stat_ownerid = Stat::makeLiteral((int64_t)ownerid);
	Stat* stat_datconnlimit = Stat::makeLiteral((int64_t)datconnlimit);
	Stat* stat_curconnect = Stat::makeLiteral((int64_t)curconnect);
	vector<Stat*> acl;
	vector<int>::iterator iter;
	for (iter = datacl.begin(); iter != datacl.end(); iter++)
	{
		acl.push_back(Stat::makeLiteral((int64_t)(*iter)));
	}
	Stat* stat_datacl = Stat::makeArray(&acl);

	//生成最终要放入的final
	vector<Stat*> statlist;
	statlist.push_back(stat_oid);
	statlist.push_back(stat_datname);
	statlist.push_back(stat_ownerid);
	statlist.push_back(stat_datconnlimit);
	statlist.push_back(stat_curconnect);
	statlist.push_back(stat_datacl);
	Stat* final = Stat::makeArray(&statlist);


	//放入页中
	string rowid;
	Page* targetblock = FileManager::getInstance()->getLastAvailablePage(fileid);		//取得file的最后一个可用的页
	targetblock->setPageType(PageType::dictionary);
	rowid = targetblock->put(final);									//将数据放入可以放入的页

	targetblock->updateBuffer();

	Dict::roidmap[oid] = make_pair(DatabaseRoid, rowid);
}

/*-------------------------------------------------*/

/*-------------------------------------------------*/
Class::Class()
{
	reltuples = 0;
	hasindex = 0;
	relnatts = 0;
	haspkey = 0;
	file file_class = file(2);
	fileid = file_class.fileid64;
}

void Class::AddTuples(int num)
{
	reltuples = reltuples + num;
}

void Class::DeleteTuples(int num) {
	reltuples = reltuples - num;
}

bool Class::HasIndex() {
	if (hasindex == 1) {
		return true;
	}
	else {
		return false;
	}
}

void Class::Setindex(bool t) {
	if (t == true)
		hasindex = 1;
	else
		hasindex = 0;
}

bool Class::HasPkey() {
	if (haspkey == 1) {
		return true;
	}
	else {
		return false;
	}
}

void Class::SetPkey(bool t) {
	if (t == true)
		haspkey = 1;
	else
		haspkey = 0;
}

void Class::updateFile()
{
	Stat* stat_oid = Stat::makeLiteral((int64_t)oid);
	Stat* stat_databaseid = Stat::makeLiteral((int64_t)databaseid);
	Stat* stat_relname = Stat::makeLiteral(relname.data());
	Stat* stat_relfileid = Stat::makeLiteral(relfileid.data());
	Stat* stat_relblockid = Stat::makeLiteral(relblockid.data());
	Stat* stat_reltuples = Stat::makeLiteral((int64_t)reltuples);
	Stat* stat_hasindex = Stat::makeLiteral((int64_t)hasindex);
	Stat* stat_relkind = Stat::makeLiteral(&relkind);
	Stat* stat_relnatts = Stat::makeLiteral((int64_t)relnatts);
	Stat* stat_haspkey = Stat::makeLiteral((int64_t)haspkey);

	//生成最终要放入的final
	vector<Stat*> statlist;
	statlist.push_back(stat_oid);
	statlist.push_back(stat_databaseid);
	statlist.push_back(stat_relname);
	statlist.push_back(stat_relfileid);
	statlist.push_back(stat_relblockid);
	statlist.push_back(stat_reltuples);
	statlist.push_back(stat_hasindex);
	statlist.push_back(stat_relkind);
	statlist.push_back(stat_relnatts);
	statlist.push_back(stat_haspkey);
	Stat* final = Stat::makeArray(&statlist);
	FileManager::getInstance()->update(Dict::getRowid(oid).c_str(), final);
}

void Class::StoreToFile() {
	//生成各条要放入的数据
	Stat* stat_oid = Stat::makeLiteral((int64_t)oid);
	Stat* stat_databaseid = Stat::makeLiteral((int64_t)databaseid);
	Stat* stat_relname = Stat::makeLiteral(relname.data());
	Stat* stat_relfileid = Stat::makeLiteral(relfileid.data());
	Stat* stat_relblockid = Stat::makeLiteral(relblockid.data());
	Stat* stat_reltuples = Stat::makeLiteral((int64_t)reltuples);
	Stat* stat_hasindex = Stat::makeLiteral((int64_t)hasindex);
	Stat* stat_relkind = Stat::makeLiteral(&relkind);
	Stat* stat_relnatts = Stat::makeLiteral((int64_t)relnatts);
	Stat* stat_haspkey = Stat::makeLiteral((int64_t)haspkey);

	//生成最终要放入的final
	vector<Stat*> statlist;
	statlist.push_back(stat_oid);
	statlist.push_back(stat_databaseid);
	statlist.push_back(stat_relname);
	statlist.push_back(stat_relfileid);
	statlist.push_back(stat_relblockid);
	statlist.push_back(stat_reltuples);
	statlist.push_back(stat_hasindex);
	statlist.push_back(stat_relkind);
	statlist.push_back(stat_relnatts);
	statlist.push_back(stat_haspkey);
	Stat* final = Stat::makeArray(&statlist);

	//放入页中
	string rowid;
	Page* targetblock = FileManager::getInstance()->getLastAvailablePage(fileid);		//取得file的最后一个可用的页
	rowid = targetblock->put(final);									//将数据放入可以放入的页
	targetblock->updateBuffer();

	Dict::roidmap[oid] = make_pair(ClassRoid, rowid);
}


/*-------------------------------------------------*/

/*-------------------------------------------------*/
Attribute::Attribute() {
	varcharlen = 10;
	notnull = 0;
	pkey = 0;
	colcard = 0;
	file file_attribute = file(3);
	fileid = file_attribute.fileid64;
}

int Attribute::GetRelid() {
	return relid;
}

void Attribute::SetRelid(int trelid) {
	relid = trelid;
}

string Attribute::GetAttritubeName() {
	return name;
}

void Attribute::SetAttritubeName(string name) {
	this->name = name;
}

StatType Attribute::GetType() {
	return type;
}

void Attribute::SetType(StatType ttype) {
	type = ttype;
}

int Attribute::GetAttnum() {
	return attnum;
}

void Attribute::SetAttnum(int tnum) {
	attnum = tnum;
}

int Attribute::GetVarcharLength() {
	return varcharlen;
}

void Attribute::SetVarcharLength(int tlen) {
	varcharlen = tlen;
}

bool Attribute::IsNotNull() {
	if (notnull == 1) {
		return true;
	}
	else {
		return false;
	}
}

void Attribute::SetNotNull(bool t) {
	if (t == true)
		notnull = 1;
	else
		notnull = 0;
}

bool Attribute::IsPkey() {
	if (pkey == 1) {
		return true;
	}
	else {
		return false;
	}
}

void Attribute::SetPkey(bool t) {
	if (t == true)
		pkey = 1;
	else
		pkey = 0;
}

int Attribute::GetColcard() {
	return colcard;
}

void Attribute::CalculateColcard() {
	//此处需要调用统计方法，统计该属性的不同元组个数
}

void Attribute::updateFile()
{
	Stat* stat_oid = Stat::makeLiteral((int64_t)oid);
	Stat* stat_relid = Stat::makeLiteral((int64_t)relid);
	Stat* stat_name = Stat::makeLiteral(name.data());
	Stat* stat_type = Stat::makeLiteral((int64_t)type);
	Stat* stat_attnum = Stat::makeLiteral((int64_t)attnum);
	Stat* stat_varcharlen = Stat::makeLiteral((int64_t)varcharlen);
	Stat* stat_notnull = Stat::makeLiteral((int64_t)notnull);
	Stat* stat_pkey = Stat::makeLiteral((int64_t)pkey);
	Stat* stat_colcard = Stat::makeLiteral((int64_t)colcard);

	//生成最终要放入的final
	vector<Stat*> statlist;
	statlist.push_back(stat_oid);
	statlist.push_back(stat_relid);
	statlist.push_back(stat_name);
	statlist.push_back(stat_type);
	statlist.push_back(stat_attnum);
	statlist.push_back(stat_varcharlen);
	statlist.push_back(stat_notnull);
	statlist.push_back(stat_pkey);
	statlist.push_back(stat_colcard);
	Stat* final = Stat::makeArray(&statlist);

	FileManager::getInstance()->update(Dict::getRowid(oid).c_str(), final);
}

void Attribute::StoreToFile() {
	//生成各条要放入的数据

	Stat* stat_oid = Stat::makeLiteral((int64_t)oid);
	Stat* stat_relid = Stat::makeLiteral((int64_t)relid);
	Stat* stat_name = Stat::makeLiteral(name.data());
	Stat* stat_type = Stat::makeLiteral((int64_t)type);
	Stat* stat_attnum = Stat::makeLiteral((int64_t)attnum);
	Stat* stat_varcharlen = Stat::makeLiteral((int64_t)varcharlen);
	Stat* stat_notnull = Stat::makeLiteral((int64_t)notnull);
	Stat* stat_pkey = Stat::makeLiteral((int64_t)pkey);
	Stat* stat_colcard = Stat::makeLiteral((int64_t)colcard);

	//生成最终要放入的final
	vector<Stat*> statlist;
	statlist.push_back(stat_oid);
	statlist.push_back(stat_relid);
	statlist.push_back(stat_name);
	statlist.push_back(stat_type);
	statlist.push_back(stat_attnum);
	statlist.push_back(stat_varcharlen);
	statlist.push_back(stat_notnull);
	statlist.push_back(stat_pkey);
	statlist.push_back(stat_colcard);
	Stat* final = Stat::makeArray(&statlist);


	//放入页中
	string rowid;
	Page* targetblock = FileManager::getInstance()->getLastAvailablePage(fileid);		//取得file的最后一个可用的页
	rowid = targetblock->put(final);									//将数据放入可以放入的页
	targetblock->updateBuffer();

	Dict::roidmap[oid] = make_pair(AttributeRoid, rowid);
}


/*-------------------------------------------------*/

/*-------------------------------------------------*/
Index::Index() {
	indtype = 'a';
	file file_index = file(4);
	fileid = file_index.fileid64;
}

int Index::GetIndexrelid() {
	return indexrelid;
}

void Index::SetIndexrelid(int tid)
{
	indexrelid = tid;
}

int Index::GetIndrelid() {
	return indrelid;
}

void Index::SetIndrelid(int tid) {
	indrelid = tid;
}

int Index::GetIndnatts() {
	return indnatts;
}

void Index::SetIndnatts(int tnum) {
	indnatts = tnum;
}

string Index::GetName() {
	return name;
}

void Index::SetName(string tname) {
	name = tname;
}

char Index::GetIndtype() {
	return indtype;
}

void Index::SetIndetype(char type) {
	indtype = type;
}

vector<int> Index::GetIndkeys() {
	return indkeys;
}

void Index::SetIndkeys(vector<int> keys) {
	indkeys = keys;
}

void Index::StoreToFile() {
	//生成各条要放入的数据
	Stat* stat_indexrelid = Stat::makeLiteral((int64_t)indexrelid);
	Stat* stat_indrelid = Stat::makeLiteral((int64_t)indrelid);
	Stat* stat_indnatts = Stat::makeLiteral((int64_t)indnatts);
	Stat* stat_name = Stat::makeLiteral(name.data());
	Stat* stat_indtype = Stat::makeLiteral(&indtype);
	vector<Stat*> acl;
	vector<int>::iterator iter;
	for (iter = indkeys.begin(); iter != indkeys.end(); iter++)
	{
		acl.push_back(Stat::makeLiteral((int64_t)(*iter)));
	}
	Stat* stat_indkeys = Stat::makeArray(&acl);

	//生成最终要放入的final
	vector<Stat*> statlist;
	statlist.push_back(stat_indexrelid);
	statlist.push_back(stat_indrelid);
	statlist.push_back(stat_indnatts);
	statlist.push_back(stat_name);
	statlist.push_back(stat_indtype);
	statlist.push_back(stat_indkeys);
	Stat* final = Stat::makeArray(&statlist);

	//放入页中
	string rowid;
	Page* targetblock = FileManager::getInstance()->getLastAvailablePage(fileid);		//取得file的最后一个可用的页
	rowid = targetblock->put(final);									//将数据放入可以放入的页
	targetblock->updateBuffer();

}

/*-------------------------------------------------*/

